import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Thomas class
 * @author Hugo Armando Rodríguez Flores
 * @version 15 de Abril de 2013
 */
public class Thomas extends Ninja
{
    private int lifePercentage; //Life starts at 100%
    private int lives;  //Starts with 3 lives
    private int points; //Starts with 0 points
    private boolean liveChange; //Cheks whether the current live has changed.
    private int newLifeCounter; //If it reachs to ten(10), it will give you another life
    private boolean imageBar;   //True when new image for the bar is needed
    
    /**
     * Defines the properties for thomas.
     */
    public Thomas()
    {
        super();
        super.storeImages(7, "ryu");
        lifePercentage=100;
        newLifeCounter=points=0;
        lives=3;
        liveChange=false;
    }
    
    /**
     * Makes the Thomas act in the world
     */
    public void act() 
    {
        this.move();
        this.knifeDetection();
        this.antidoteDetection();
        this.lowLives();
        this.relocateThomas();
        this.death();
    }
    
    /**
     * Thomas movement
     */
    public void move()
    {
        Actor decPiece=null;
        if (Greenfoot.isKeyDown("right") && !Greenfoot.isKeyDown("z"))
        {
            decPiece=getOneObjectAtOffset(2, 0, Decoracion.class);
            if(decPiece==null || decPiece instanceof Puente)
            {
                if (super.getDirection())
                    super.setDirectionFlag(true);
                super.setDirection(false);
                super.realocate(1, 0);
            }
        }
        if(Greenfoot.isKeyDown("down") && !Greenfoot.isKeyDown("z"))
        {
            decPiece=getOneObjectAtOffset(0, 1, Decoracion.class);
            if(decPiece==null || decPiece instanceof Puente)
                super.realocate(0, 1);
        }
        if (Greenfoot.isKeyDown("up") && !Greenfoot.isKeyDown("z"))
        {
            decPiece=getOneObjectAtOffset(0, -6, Decoracion.class);
            if(decPiece==null || decPiece instanceof Puente)
                super.realocate(0, -1);
        }
        if (Greenfoot.isKeyDown("left") && !Greenfoot.isKeyDown("z"))
        {
            decPiece=getOneObjectAtOffset(-2, 0, Decoracion.class);
            if(decPiece==null || decPiece instanceof Puente)
            {
                if (!super.getDirection())
                    super.setDirectionFlag(true);
                super.setDirection(true);
                super.realocate(-1, 0);
            }
        }
        if (Greenfoot.isKeyDown("z"))
            this.attack();
        if (!Greenfoot.isKeyDown("right") && !Greenfoot.isKeyDown("down") && !Greenfoot.isKeyDown("up") && !Greenfoot.isKeyDown("left") && !Greenfoot.isKeyDown("z"))
            this.setImage(super.getElement(0));
    }
    
    /**
     * It gives the animation for Thomas
     */
    public void movementAnimation()
    {
        super.reverseImages();
        switch (super.getMoveCounter())
        {
            case 0: this.setImage(super.getElement(1));  super.moveCounterIncr();  break;
            case 3: this.setImage(super.getElement(2));  super.moveCounterIncr();  break;
            case 6: this.setImage(super.getElement(3));  super.moveCounterIncr();  break;
            case 9:    super.setMoveCounter(0);  break;
            default: super.moveCounterIncr();
        }
    }
    
    /**
     * It detects a knife in front of Thomas
     */
    public void knifeDetection()
    {
        Actor knife=this.getOneIntersectingObject(Cuchillo.class);
        World world=getWorld();
        if (knife!=null)
        {
            points-=50;
            lifePercentage-=10;
            imageBar=true;
            ((Escenario)world).messages();
            world.removeObject(knife);
        }
    }
    
    /**
     * This checks when lifePercentage is below 0, then lows one of the lives.
     */
    public void lowLives()
    {
        if (lifePercentage<=0)
        {
            liveChange=true;
            lifePercentage=100;
            lives--;
            World world=getWorld();
            ((Escenario)world).messages();
        }
    }
    
    /**
     * This allows the enemies inflict damage.
     * @param damage is the damage one enemy has inflicted on him
     */
    public void lowLifePercentageFromOutside(int damage)
    {
        lifePercentage-=damage;
        imageBar=true;
        World world=getWorld();
        ((Escenario)world).messages();
    }
    
    /**
     * It detects an antidote in front of Thomas
     */
    public void antidoteDetection()
    {
        Actor antidoto=null;
        antidoto=this.getOneIntersectingObject(Antidoto.class);
        if (antidoto!=null)
        {
            if (antidoto instanceof MagicJar)
            {
                lifePercentage+=100-lifePercentage;
                points+=100;
                newLifeCounter++;
                if (newLifeCounter==10)
                {
                    lives+=1;
                    newLifeCounter=0;
                }
            }
            if (antidoto instanceof DoomJar)
            {
                lifePercentage-=lifePercentage;
                points-=150;
            }
            ((Escenario)getWorld()).messages();
            getWorld().removeObject (antidoto);
        }
    }
    
    /**
     * This will Thomas who is attacking, and will assing the corresponding points depending on this.
     */
    public void enemyDetection()
    {
        Actor enemigo=null;
        enemigo=this.getOneIntersectingObject(Enemigo.class);
        if (enemigo!=null)
        {
            if (enemigo instanceof Buck)
                points+=100;
            if (enemigo instanceof Rick)
                points+=80;
            if (enemigo instanceof Julius)
                points+=120;
            if (enemigo instanceof Gigante)
                points+=250;
            if (enemigo instanceof Swordsman)
                points+=320;
            if (enemigo instanceof MrZ)
                points+=400;
            if (enemigo instanceof Ordinario)
                ((Ordinario)enemigo).setRemoveFlag(true);
            if (enemigo instanceof Jefe)
                ((Jefe)enemigo).setLifePercentage(5);
            ((Escenario)this.getWorld()).messages();
        }
    }
    
    /**
     * Puts the animations when thomas is attacking.
     */
    public void attack()
    {
        switch (super.getAttackCounter())
        {
            case 0: this.setImage(super.getElement(4));  super.attackCounterIncr();  break;
            case 5: this.setImage(super.getElement(5));  this.enemyDetection();  super.attackCounterIncr();  break;
            case 10: this.setImage(super.getElement(6)); this.enemyDetection();  super.attackCounterIncr();  break;
            case 15:    super.setAttackCounter(0);  this.enemyDetection();  break;
            default: super.attackCounterIncr();
        }
    }
    
    /**
     * Informs the world when Thomas has lose.
     */
    public void death()
    {
        if (lives==0 || ((Escenario)getWorld()).getTimer().getElapsedTime()==0)
        {
            getWorld().addObject(new Mensaje("You lost!!", 40), getWorld().getWidth()/2, getWorld().getHeight()/2);
            ((Escenario)getWorld()).getRecords().storeScore(points);
            Greenfoot.delay(75);
            ((Escenario)getWorld()).didYouLost(true);
        }
    }
    
    /**
     * When Thomas lose a life, this will realocate thomas where he started depending on the current stage.
     */
    public void relocateThomas()
    {
        if (liveChange && lives>0)
        {
            switch(((Escenario)getWorld()).getStage())
            {
                case 1: this.setLocation(13, 51); break;
                case 2: this.setLocation(13, 157); break;
                case 3: this.setLocation(237, 50); break;
            }
            liveChange=false;
        }
    }
    
    /**
     * @return the actual lifePercentage of Thomas
     */
    public int retLifePercentage()
    {
        return lifePercentage;
    }
    
    /**
     * @return the current lives of Thomas
     */
    public int retLives()
    {
        return lives;
    }
    
    /**
     * @return the current points of Thomas
     */
    public int retPoints()
    {
        return points;
    }
    
    /**
     * @return the flag when a live change has ocurred.
     */
    public boolean getLiveChange()
    {
        return liveChange;
    }
    
    /**
     * Sets the live change a new flag.
     * @param newFlag is the flag that is going to be assigned to liveChange
     */
    public void setLiveChange(boolean newFlag)
    {
        liveChange=newFlag;
    }
}
